package com.yt.common.utils;

import java.math.BigDecimal;
import java.text.DecimalFormat;

/**
 * @Description ：精准的加减乘除
 * @Author ： 解风
 * @Date ： 2018/01/02 15:40
 */
public class BigDecimalUtils {
	
	/**
	 * 默认保留位：2
	 */
	private static int 	DEFAULT_SCALE = 2;
	private static int 	SCALE_8 = 8;

	/**
	 * 默认四舍五入规则为：向上舍入
	 */
	private static int ROUND_HALF_UP = BigDecimal.ROUND_HALF_UP;

	/**
	 * 默认四舍五入规则为：向下舍入
	 */
	private static int ROUND_HALF_DOWN = BigDecimal.ROUND_HALF_DOWN;

	/**
	 * 默认四舍五入规则为：直接删除多余 如：2.58-2.5
	 */
	private static int ROUND_DOWN = BigDecimal.ROUND_DOWN;

	/**
	 * 默认四舍五入规则为：进位处理 如：2.12-2.2
	 */
	private static int ROUND_UP = BigDecimal.ROUND_UP;

	/**
	 * 获取BigDecimal
	 * @param value
	 * @param scale
	 * @return
	 */
	public static BigDecimal getBigDecimal(Object value,Integer scale){
		if (null == scale){
			scale=DEFAULT_SCALE;
		}
		if (null == value){
			return new BigDecimal(0.00);
		}
		BigDecimal big = getBigDecimalObject(value);
		BigDecimal dec = big.setScale(scale,ROUND_HALF_UP);
		return dec;
	}

	/**
	 * 获取BigDecimal 保留两位小数
	 * @param value
	 * @return
	 */
	public static BigDecimal getBigDecimal(Object value){
		return getBigDecimal(value, DEFAULT_SCALE);
	}

	/**
	 * 转换Double
	 * @param value
	 * @param scale
	 * @return
	 */
	public static Double toDouble(Object value,Integer scale){
		BigDecimal d = getBigDecimal(value, scale);
		return d.doubleValue();
	}

	/**
	 * 转换Double 保留两位小数
	 * @param value
	 * @return
	 */
	public static Double toDouble(Object value){
		return toDouble(value, DEFAULT_SCALE);
	}

	/**
	 * 转换Double
	 * @param value 值
	 * @param scale 保留小数
	 * @return
	 */
	public static Integer toInteger(Object value,Integer scale){
		BigDecimal d = getBigDecimal(value, scale);
		return d.intValue();
	}

	/**
	 * 转换Double 保留两位小数
	 * @param value
	 * @return
	 */
	public static Integer toInteger(Object value){
		return toInteger(value, DEFAULT_SCALE);
	}

	/**
	 * 转换Long
	 * @param value
	 * @param scale
	 * @return
	 */
	public static Long toLong(Object value,Integer scale){
		BigDecimal d = getBigDecimal(value, scale);
		return d.longValue();
	}

	/**
	 * 转换Long 保留两位小数
	 * @param value
	 * @return
	 */
	public static Long toLong(Object value){
		return toLong(value, DEFAULT_SCALE);
	}

	/**
	 * 转换String
	 * @param value
	 * @param scale
	 * @return
	 */
	public static String toString(Object value,Integer scale){
		BigDecimal d = getBigDecimal(value, scale);
		return d.toString();
	}

	/**
	 * 转换String 保留两位小数
	 * @param value
	 * @return
	 */
	public static String toString(Object value){
		return toString(value, DEFAULT_SCALE);
	}
	/**
	 * 转换String 去掉科学技术法
	 * @param value
	 * @param scale
	 * @return
	 */
	public static String toPlainString(Object value,Integer scale){
		BigDecimal d = getBigDecimal(value, scale);
		return d.toPlainString();
	}

	/**
	 * 转换String 保留两位小数 去掉科学技术法
	 * @param value
	 * @return
	 */
	public static String toPlainString(Object value){
		return toPlainString(value, DEFAULT_SCALE);
	}
	/**
	 * 
	 * 加法运算
	 * @param v1	加数
	 * @param v2	被加数
	 * @return
	 */
	public static BigDecimal add(Object v1,Object v2, Integer scale){
		BigDecimal b1 = getBigDecimal(v1, scale);
		BigDecimal b2 = getBigDecimal(v2, scale);
		return b1.add(b2).setScale(scale,BigDecimal.ROUND_HALF_UP);
	}

	public static BigDecimal add(Object v1,Object v2){
		return add(v1, v2, DEFAULT_SCALE);
	}
	/**
	 * 减法
	 * @param v1
	 * @param v2
	 * @return
	 */
	public static BigDecimal sub(Object v1,Object v2, Integer scale){
		BigDecimal b1 = getBigDecimal(v1, scale);
		BigDecimal b2 = getBigDecimal(v2, scale);
		return b1.subtract(b2).setScale(scale,BigDecimal.ROUND_HALF_UP);
	}
	public static BigDecimal sub(Object v1,Object v2){
		return sub(v1, v2, DEFAULT_SCALE);
	}
	/**
	 * 乘法  toPlainString() 去掉科学技术法
	 * @param v1
	 * @param v2
	 * @return
	 */
	public static BigDecimal multiply(Object v1,Object v2, Integer scale){
		BigDecimal b1 = getBigDecimal(v1, scale);
		BigDecimal b2 = getBigDecimal(v2, scale);
		return b1.multiply(b2).setScale(scale,BigDecimal.ROUND_HALF_UP);
	}

	public static BigDecimal multiply(Object v1,Object v2){
		return multiply(v1, v2, DEFAULT_SCALE);
	}

	/**
	 * 乘法  toPlainString() 去掉科学技术法
	 * @param v1
	 * @param v2
	 * @return
	 */
	public static String  multiplyStr(Object v1,Object v2, Integer scale){
		return multiply(v1, v2, scale).toPlainString();
	}
	public static String  multiplyStr(Object v1,Object v2){
		return multiplyStr(v1, v2, DEFAULT_SCALE);
	}



	/**
	 * 除法运算<br>
	 * 当发生除不尽的情况时，由scale参数指定精度，以后的数字四舍五入。
	 *
	 * @param v1 除数
	 * @param v2 被除数
	 * @param scale 精确精度
	 * @return
	 */
	public static BigDecimal divide(Object v1,Object v2, Integer scale){
		BigDecimal b1 = getBigDecimal(v1, scale);
		BigDecimal b2 = getBigDecimal(v2, scale);
		return b1.divide(b2, scale);
	}
	public static BigDecimal divide(Object v1,Object v2){
		return divide(v1, v2, DEFAULT_SCALE);
	}

	/**
	 * 比较两个数<br>
	 * v1 > v2 return 1<br>
	 * v1 = v2 return 0<br>
	 * v1 < v2 return -1
	 * @param v1 比较数
	 * @param v2 被比较数
	 * @return
	 */
	public static int compareTo(Object v1,Object v2, Integer scale){
		BigDecimal b1 = getBigDecimal(v1, scale);
		BigDecimal b2 = getBigDecimal(v2, scale);
        return b1.compareTo(b2);    
    }
	public static int compareTo(Object v1,Object v2){
		return compareTo(v1, v2, DEFAULT_SCALE);
	}

	/**
	 * 返回较小数
	 * @param v1
	 * @param v2
	 * @return
	 */
	public static BigDecimal compareToMin(Object v1,Object v2, Integer scale){
		BigDecimal b1 = getBigDecimal(v1, scale);
		BigDecimal b2 = getBigDecimal(v2, scale);
        return b1.min(b2);
    }   
	
	/**
	 * 返回较大数
	 *
	 * @param v1
	 * @param v2
	 * @return
	 */
	public static BigDecimal compareToMax(Object v1,Object v2, Integer scale){
		BigDecimal b1 = getBigDecimal(v1, scale);
		BigDecimal b2 = getBigDecimal(v2, scale);
        return b1.max(b2);
    }

	/**
	 * 返回金额 格式为 2.00的字符串
	 *
	 * @param v1
	 * @return
	 */
	public static String interceptLastFourAmount(Object v1){
		DecimalFormat df = new DecimalFormat("#.00");
		String temp = df.format(v1);
		if (Double.valueOf(temp) >= (double) 10) {
			return temp.substring(temp.length() - 4);
		} else {
			return temp;
		}

	}

	/**
	 * 将object转换为Bigdecimal
	 *
	 * @param value 待转换的数值
	 * @return
	 */
	public static BigDecimal getBigDecimalObject(Object value){

		BigDecimal resultValue = new BigDecimal(0);
		if (null == value){
			return resultValue;
		}
		if(value instanceof String){
			if ("".equals(value)){
				return resultValue;
			}
			resultValue =  new BigDecimal((String)value);
		} else if(value instanceof Integer){
			resultValue =  new BigDecimal((Integer)value);
		} else if(value instanceof Long){
			resultValue =  new BigDecimal((Long)value);
		} else if(value instanceof Double){
			resultValue =  new BigDecimal((Double)value);
		} else if(value instanceof BigDecimal){
			resultValue = (BigDecimal) value;
		}
		
		return resultValue;
	}

	public static void main(String[] args) {
//		BigDecimal dec = new BigDecimal(1231232131231231231.123456);
//		System.out.println(dec.setScale(4, BigDecimal.ROUND_HALF_UP));
		BigDecimal b1 = getBigDecimal(10, 2);
		BigDecimal b2 = getBigDecimal(3, 2);
		System.out.println(b1 + "---" + b2);

		System.out.println(b1.divide(b2,2));
		System.out.println(b1.divide(new BigDecimal(3), 2, BigDecimal.ROUND_HALF_UP));
//		System.out.println(multiply(40000, 0.0019));
	}
}
